﻿using System;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
//using Microsoft.Security.Application;

namespace MyAMS.Utility
{
    /// <summary>
    /// 字符串扩展类
    /// </summary>
    public static class StringExtensions
    {
        private static readonly Regex cleanWhitespace = new Regex(@"\s+", RegexOptions.Compiled | RegexOptions.Singleline);

        /// <summary>
        /// 是否必须
        /// </summary>
        /// <param name="s">字符串</param>
        /// <returns></returns>
        public static string IsRequired(this string s)
        {
            if (string.IsNullOrEmpty(s))
            {
                throw new ArgumentNullException(string.Format("String is required: {0}", s));
            }

            return s;
        }

        /// <summary>
        /// Url编码
        /// </summary>
        /// <param name="input">输入字符</param>
        /// <returns>解码后的字符</returns>
        public static string UrlEncode(this string input)
        {
            return UrlEncode(input, Encoding.UTF8);
        }

        /// <summary>
        /// Url编码
        /// </summary>
        /// <param name="input">输入字符</param>
        /// <param name="encoding">编码</param>
        /// <returns>解码后的字符</returns>
        public static string UrlEncode(this string input, Encoding encoding)
        {
            return HttpUtility.UrlEncode(input, encoding);
        }

        /// <summary>
        /// Url解码
        /// </summary>
        /// <param name="input">输入字符</param>
        /// <returns>解码后的字符</returns>
        public static string UrlDecode(this string input)
        {
            return UrlDecode(input, Encoding.UTF8);
        }

        /// <summary>
        /// Url解码
        /// </summary>
        /// <param name="input">输入字符</param>
        /// <param name="encoding">编码</param>
        /// <returns>解码后的字符</returns>
        public static string UrlDecode(this string input, Encoding encoding)
        {
            return HttpUtility.UrlDecode(input, encoding);
        }

        /// <summary>
        /// Html解码
        /// </summary>
        /// <param name="input">输入字符</param>
        /// <returns>解码后的字符</returns>
        public static string HtmlDecode(this string input)
        {
            return HttpUtility.HtmlDecode(input);
        }

        /// <summary>
        /// Html编码
        /// </summary>
        /// <param name="input">输入字符</param>
        /// <returns>解码后的字符</returns>
        public static string HtmlEncode(this string input)
        {
            return HttpUtility.HtmlEncode(input);
        }

        /// <summary>
        /// 清除Html标记
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string CleanHtmlTags(this string s)
        {
            Regex exp = new Regex(
                "<[^<>]*>",
                RegexOptions.Compiled
                );

            return exp.Replace(s, "");
        }

        //TODO: (5he11)
        //public static string CleanText(this string s)
        //{
        //    return AntiXss.HtmlEncode(s);
        //}

        //public static string CleanHtml(this string s)
        //{
        //    //AntiXss library from Microsoft 
        //    //(http://codeplex.com/antixss)
        //    string encodedText = AntiXss.HtmlEncode(s);
        //    //convert line breaks into an html break tag
        //    return encodedText.Replace("&#13;&#10;", "<br />");
        //}

        //public static string CleanAttribute(this string s)
        //{
        //    return AntiXss.HtmlAttributeEncode(s);
        //}

        // rename to something more generic (CleanAttributeALittle?) because not everything needs
        // the cleaning power of CleanAttribute (everything should but AntiXss.HtmlAttributeEncode encodes 
        // *everyting* incl. white space :|) so attributes can get really long...but then my only current worry is around
        // the description meta tag. Attributes from untrusted sources *do* need the current CleanAttribute...
        //public static string CleanHref(this string s)
        //{
        //    return HttpUtility.HtmlAttributeEncode(s);
        //}

        //public static string CleanWhitespace(this string s)
        //{
        //    return cleanWhitespace.Replace(s, " ");
        //}

        //public static string CleanCommentBody(this string s)
        //{
        //    return s.CleanHtmlTags().CleanHtml().AutoAnchorEncoded();
        //}

        //private static readonly Regex uriEncodedRegex = new Regex("(^|[^\\w'\"]|\\G)(?<uri>(?:https?|ftp)&#58;&#47;&#47;(?:[^./\\s'\"<)\\]]+\\.)+[^./\\s'\"<)\\]]+(?:&#47;.*?)?)(\\.[\\s<'\"]|[\\s,<'\"]|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        //public static string AutoAnchorEncoded(this string s)
        //{
        //    MatchCollection uriMatches = uriEncodedRegex.Matches(s);

        //    foreach (Match uriMatch in uriMatches)
        //    {
        //        string encodedUri = uriMatch.Groups["uri"].Value;

        //        if (!string.IsNullOrEmpty(encodedUri))
        //        {
        //            string uri = HttpUtility.HtmlDecode(encodedUri);
        //            s = s.Replace(encodedUri, string.Format("<a href=\"{0}\">{1}</a>", uri.CleanHref(), uri.CleanText()));
        //        }
        //    }

        //    return s;
        //}

        //public static string Shorten(this string s, int characterCount)
        //{
        //    string text = !string.IsNullOrEmpty(s) ? s.CleanHtmlTags().CleanWhitespace() : "";

        //    if (!string.IsNullOrEmpty(text) && characterCount > 0 && text.Length > characterCount)
        //    {
        //        text = text.Substring(0, characterCount);
        //    }

        //    return text;
        //}

        /// <summary>
        /// 尝试解析Guid
        /// </summary>
        /// <param name="s">字符串</param>
        /// <param name="result">解析结果</param>
        /// <returns>解析是否成功</returns>
        public static bool GuidTryParse(this string s, out Guid result)
        {
            if (s == null)
            {
                throw new ArgumentNullException("s");
            }

            try
            {
                result = new Guid(s);
                return true;
            }
            catch (FormatException)
            {
                result = Guid.Empty;
                return false;
            }
            catch (OverflowException)
            {
                result = Guid.Empty;
                return false;
            }
        }

        /// <summary>
        /// 计算哈希码
        /// </summary>
        /// <param name="value">字符串</param>
        /// <returns>哈希码</returns>
        public static string ComputeHash(this string value)
        {
            string hash = value;

            if (value != null)
            {
                MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
                byte[] data = Encoding.ASCII.GetBytes(value);
                data = md5.ComputeHash(data);
                hash = "";
                for (int i = 0; i < data.Length; i++)
                {
                    hash += data[i].ToString("x2");
                }
            }

            return hash;
        }
    }
}